home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / examples / lighting / normals.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  7.4 KB  |  315 lines

  1. /* Copyright 1996 Silicon Graphics, Inc.
  2.  * All Rights Reserved.
  3.  *
  4.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  5.  * the contents of this file may not be disclosed to third parties, copied or
  6.  * duplicated in any form, in whole or in part, without the prior written
  7.  * permission of Silicon Graphics, Inc.
  8.  *
  9.  * RESTRICTED RIGHTS LEGEND:
  10.  * Use, duplication or disclosure by the Government is subject to restrictions
  11.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  12.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  13.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  14.  * rights reserved under the Copyright Laws of the United States.
  15.  */
  16.  
  17. /* normals.c - Show the effect of lighting on a flat surface
  18.  *    when using face normals and vertex normals. The red 
  19.  *    lines represent the directions of the normal vectors.
  20.  *
  21.  *    Left Mousebutton        - move eye position
  22.  *    Middle Mousebutton      - change twist angle
  23.  *    Right Mousebutton       - move up / down to zoom in / out
  24.  *    Escape Key              - exit the program
  25.  */
  26.  
  27. #include <GL/gl.h>
  28. #include <GL/glu.h>
  29. #include <GL/glut.h>
  30.  
  31. #include "3d.h"
  32. #include <math.h>
  33. #include <stdio.h>
  34.  
  35. /*  Function Prototypes  */
  36.  
  37. GLvoid  initgfx( GLvoid );
  38. GLvoid  drawScene( GLvoid );
  39. GLvoid  reshape( GLsizei, GLsizei );
  40. GLvoid  keyboard( GLubyte, GLint, GLint );
  41. GLvoid  mouse( GLint, GLint, GLint, GLint );
  42. GLvoid  motion( GLint, GLint );
  43.  
  44. GLvoid  drawNormal( GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat );
  45.  
  46. void resetView( GLvoid );
  47. void polarView( GLfloat, GLfloat, GLfloat, GLfloat );
  48. void printHelp( char * );
  49.  
  50. /* Global Definitions */
  51.  
  52. #define KEY_ESC    27    /* ascii value for the escape key */
  53.  
  54. /* Global Variables */
  55.  
  56. static enum        actions { MOVE_EYE, TWIST_EYE, ZOOM, MOVE_NONE };
  57. static GLint        action;
  58.  
  59. static GLdouble        xStart = 0.0, yStart = 0.0;
  60.  
  61. static GLfloat         fovy, near, far, distance, twistAngle, incAngle, azimAngle;
  62.  
  63. void
  64. main( int argc, char *argv[] )
  65. {
  66.     GLsizei width, height;
  67.  
  68.     glutInit( &argc, argv );
  69.  
  70.     /* create a window that is 1/4 the size of the screen */
  71.  
  72.     width = glutGet( GLUT_SCREEN_WIDTH ); 
  73.     height = glutGet( GLUT_SCREEN_HEIGHT );
  74.     glutInitWindowPosition( width / 4, height / 4 );
  75.     glutInitWindowSize( (width / 2) - 4, height / 2 );
  76.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
  77.     glutCreateWindow( argv[0] );
  78.  
  79.     initgfx();
  80.  
  81.     glutMouseFunc( mouse );
  82.     glutMotionFunc( motion );
  83.     glutKeyboardFunc( keyboard );
  84.     glutReshapeFunc( reshape );
  85.     glutDisplayFunc( drawScene ); 
  86.  
  87.     printHelp( argv[0] );
  88.  
  89.     glutMainLoop();
  90. }
  91.  
  92. void
  93. printHelp( char *progname )
  94. {
  95.     fprintf(stdout, "\n%s - demonstrate face and vertex normals\n\n" 
  96.         "Left Mousebutton    - move eye position\n"
  97.         "Middle Mousebutton    - change twist angle\n"
  98.         "Right Mousebutton    - move up / down to zoom in / out\n"
  99.         "Escape Key        - exit the program\n\n",
  100.         progname);
  101. }
  102.  
  103. GLvoid
  104. initgfx( GLvoid )
  105. {
  106.     glClearColor( 0.0, 0.0, 0.0, 1.0 );
  107.     glEnable( GL_DEPTH_TEST );
  108.  
  109.     fovy = 60.0;    /* field of view in Y */
  110.     near = 3.0;    /* Near clipping plane location */
  111.     far  = 12.0;    /* Far clipping plane location */
  112.  
  113.     resetView();
  114.  
  115.     /* Turn on a default light */
  116.     glEnable( GL_LIGHT0 );
  117. }
  118.  
  119. GLvoid 
  120. keyboard( GLubyte key, GLint x, GLint y )
  121. {
  122.     switch (key) {
  123.     case KEY_ESC:    /* Exit whenever the Escape key is pressed */
  124.         exit(0);
  125.     }
  126. }
  127.  
  128. GLvoid 
  129. mouse( GLint button, GLint state, GLint x, GLint y )
  130. {
  131.     static GLint buttons_down = 0;
  132.  
  133.     if (state == GLUT_DOWN) {
  134.         switch (button) {
  135.         case GLUT_LEFT_BUTTON:
  136.             action = MOVE_EYE;
  137.             break;
  138.         case GLUT_MIDDLE_BUTTON:
  139.             action = TWIST_EYE;
  140.             break;
  141.         case GLUT_RIGHT_BUTTON:
  142.             action = ZOOM;
  143.             break;
  144.         }
  145.  
  146.         /* Update the saved mouse position */
  147.         xStart = x;
  148.         yStart = y;
  149.     } else {
  150.         if (--buttons_down == 0) 
  151.             action = MOVE_NONE;
  152.     }
  153.  
  154. }
  155.  
  156. GLvoid
  157. motion( GLint x, GLint y )
  158. {
  159.     switch (action) {
  160.     case MOVE_EYE:
  161.         /* Adjust the eye position based on the mouse position */
  162.         azimAngle += (GLdouble) (x - xStart);
  163.         incAngle -= (GLdouble) (y - yStart);
  164.         break;
  165.     case TWIST_EYE:
  166.         /* Adjust the eye twist based on the mouse position */
  167.         twistAngle = fmodf(twistAngle+(x - xStart), 360.0);
  168.         break;
  169.     case ZOOM:
  170.         /* Adjust the eye distance based on the mouse position */
  171.         distance -= (GLdouble) (y - yStart)/10.0;
  172.         break;
  173.     default:
  174.         printf("unknown action %d\n", action);
  175.     }
  176.     
  177.     /* Update the stored mouse position for later use */
  178.     xStart = x;
  179.     yStart = y;
  180.  
  181.     glutPostRedisplay();
  182. }
  183.  
  184. void
  185. resetView( GLvoid )
  186. {
  187.     distance = near + (far - near) / 2.0;
  188.     twistAngle = 0.0;    /* rotation of viewing volume (camera) */
  189.     incAngle = 60.0;
  190.     azimAngle = 0.0;
  191.     fovy = 60.0;    /* Field of view in Y angle */
  192. }
  193.  
  194. GLvoid
  195. reshape( GLsizei width, GLsizei height )
  196. {
  197.     GLdouble    aspect;
  198.  
  199.     glViewport( 0, 0, width, height );
  200.  
  201.     aspect = (GLdouble) width / (GLdouble) height;
  202.  
  203.     glMatrixMode( GL_PROJECTION );
  204.     glLoadIdentity();
  205.     gluPerspective( fovy, aspect, near, far );
  206.     glMatrixMode( GL_MODELVIEW );
  207. }
  208.  
  209. void
  210. polarView( GLfloat distance, GLfloat azimuth, GLfloat incidence,
  211.             GLfloat twist)
  212. {
  213.     glTranslatef( 0.0, 0.0, -distance);
  214.     glRotatef( -twist, 0.0, 0.0, 1.0);
  215.     glRotatef( -incidence, 1.0, 0.0, 0.0);
  216.     glRotatef( -azimuth, 0.0, 0.0, 1.0);
  217. }
  218.  
  219. GLvoid
  220. drawNormal( GLfloat px, GLfloat py, GLfloat pz,
  221.     GLfloat nx, GLfloat ny, GLfloat nz )
  222. {
  223.     GLdouble normal[3], cross[3], zaxis[3];
  224.     GLdouble angle;
  225.  
  226. #define DegreesToRadians        (M_PI / (GLfloat) 180.0)
  227.  
  228.     glColor3f( 1.0, 0.0, 0.0 );
  229.     glPushMatrix();
  230.         glTranslatef( px, py, pz );
  231.         glBegin( GL_LINES );
  232.             glVertex3f( 0.0, 0.0, 0.0 );
  233.             glVertex3f( nx, ny, nz );
  234.         glEnd();
  235.  
  236.         /* normalize the normal vector */
  237.         normal[0] = nx; normal[1] = ny; normal[2] = nz;
  238.         normalize( normal );
  239.  
  240.         /* determine angle between z axis and normal */
  241.         zaxis[0] = 0; zaxis[1] = 0; zaxis[2] = 1;
  242.         angle = acos( dot3( zaxis, normal ) )/DegreesToRadians;
  243.         
  244.         if ( angle != 0.0 ) {
  245.             /* find the axis of rotation */
  246.             crossprod( zaxis, normal, cross );
  247.             glRotatef( angle, cross[0], cross[1], cross[2] );
  248.         }
  249.         /* move to end of normal vector */
  250.         glTranslatef( 0.0, 0.0, 1.0 );
  251.         glutSolidCone( 0.05, 0.1, 8, 8 );
  252.     glPopMatrix();
  253. }
  254.  
  255. GLvoid
  256. drawScene( GLvoid )
  257. {
  258.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  259.  
  260.     glPushMatrix();
  261.  
  262.         polarView( distance, azimAngle, incAngle, twistAngle );
  263.  
  264.         /* Draw a lit flat-shaded triangle on the left */
  265.         glPushMatrix();
  266.             glTranslatef( -2.0, 0.0, 0.0 );
  267.  
  268.             /* Turn on lighting computations */
  269.             glEnable( GL_LIGHTING );
  270.  
  271.             glBegin( GL_TRIANGLES );
  272.                 glNormal3f( 0.0, 0.0, 1.0 );
  273.                 glVertex2f( 0.0, 1.0 );
  274.                 glVertex2f( -0.866, -0.50 );
  275.                 glVertex2f( 0.866, -0.50 );
  276.             glEnd();
  277.  
  278.             /* Turn off lighting computations */
  279.             glDisable( GL_LIGHTING );
  280.             
  281.             /* Draw an unlit line representing the face normal */
  282.             drawNormal( 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 );
  283.         glPopMatrix();
  284.  
  285.         /* Draw a lit, smooth-shaded triangle on the right */
  286.         glPushMatrix();
  287.             glTranslatef( 2.0, 0.0, 0.0 );
  288.  
  289.             /* Turn on lighting computations */
  290.             glEnable( GL_LIGHTING );
  291.  
  292.             glBegin( GL_TRIANGLES );
  293.                 glNormal3f( 0.0, 0.0, 1.0 );
  294.                 glVertex2f( 0.0, 1.0 );
  295.                 glNormal3f( 0.455, 0.796, 0.398 );
  296.                 glVertex2f( -0.866, -0.50 );
  297.                 glNormal3f( 0.162, 0.566, 0.808 );
  298.                 glVertex2f( 0.866, -0.50 );
  299.             glEnd();
  300.  
  301.             /* Turn off lighting computations */
  302.             glDisable( GL_LIGHTING );
  303.  
  304.             /* Draw unlit lines representing the vertex normals */
  305.             drawNormal( 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
  306.             drawNormal( -0.866, -0.50, 0.0, 0.455, 0.796, 0.398 );
  307.             drawNormal( 0.866, -0.50, 0.0, 0.162, 0.566, 0.808 );
  308.         glPopMatrix();
  309.  
  310.  
  311.     glPopMatrix();
  312.  
  313.     glutSwapBuffers();
  314. }
  315.